iT邦幫忙

2022 iThome 鐵人賽

DAY 15
1
Modern Web

前端技能樹的十萬個為什麼系列 第 15

Day 15 - 為什麼要用 RESTful API

  • 分享至 

  • xImage
  •  

前言

RESTful API 應該算是我的「一知半解清單」中,名列前茅的前幾名,可能跟 Day 3 的 MVC 有得比XD

之所以介於「會」與「不會」之間,就是因為 RESTful API 並不是一個強硬的規範,即便不照著規範寫,也是可以活得好好的,所以就更難有機會去回首看看,自己寫出來的 API,真的可以稱為「RESTful」嗎?

雖然 API 的範疇更接近後端一點,不過前端肯定也是逃不掉的XD 今天就來好好面對吧!

先想一下

  • RESTful API 是在什麼樣的時代誕生的?
  • RESTful API 怎麼解決問題?
  • RESTful API 的優缺點是什麼?
  • RESTful API 適合什麼情境?

RESTful API 是在什麼樣的時代誕生的?

REST 其實也只是一個風格,符合 REST 風格的 API 就叫做 RESTful API,而還沒有這個風格出現之前,API 沒有明確可遵循的風格,往往是自由心證的:

  • POST /updateUser?userId=1
  • POST /user/update/1
  • PUT /update/user/1

基本上只要後端有對應的 route 可以處理,無論寫成怎樣都可以運作,但一來團隊沒有一致的風格,二來也會讓每一支 API 的功能變得模稜兩可無法推測,因為一定要看後端對應的 controller 處理邏輯,才有辦法知道實際功用。

RESTful API 怎麼解決問題?

RESTful API 是由三個部分組成的,Nouns(URI)、Verb(HTTP method)Content-Types

  • 使用 URI 來表示網路上的資源本體
  • 使用 JSON 或 XML 等 content-type 來表示這個資源
  • 使用 GET 或 POST 之類的 HTTP method 來針對資源操作狀態轉化

舉簡單的例子來說,我如果要做到「建立會員」這件事,就是:

  • URI: /member
  • Content-Type: application/json
  • HTTP method: POST

代表:我要建立「member」這個資源,並且會傳送 json 格式的資料給後端。

URI 不能帶有動詞

這邊有個容易出事的地方,那就是 URI 不能帶有動詞,因為 HTTP method 才是真正代表動詞的角色,而 URI 只能代表資源,是一個名詞,兩者不可混為一談。

如果你也訂過 POST /signup 這種 API,那現在明白它不是 RESTful API 了 QWQ

透過抽象化帶來的和平

其實一句話來說,RESTful API 就是在要求「正確將資源抽象化」,基本上只要 URI 寫對了,不要寫出 /createUser 之類的 URI,就不太會錯了(畢竟 HTTP method 就那幾個讓你選而已)。

而正確抽象化之後帶來的益處,就是讓前後端之間的溝通更有規範對於「資源」的操作更加一致,減少模稜兩可的空間,比如以下比較:

POST /user:單純建立 user,沒了

v.s.

POST /signup:不確定除了建立 user 外還會做什麼事情

RESTful API 的優缺點是什麼?

優點

  • 「行為」(HTTP method)、「資源」(URI)切割分離,確保明確的操作行為,降低複雜度
  • 每個 API 專注做一件事,提高各種組合的可能性

缺點

  • 若一次需要操作多個資源,還是得乖乖發送多個 request,效能方面較差
  • 網路上所有東西都是「資源」,但正確將資源抽象化,寫出資源的 URI,並使用正確的動詞(HTTP method) 去操作它,學習曲線較高

資源抽象化補充

關於缺點第二點,舉一個我查到很有趣的例子來說,我們都會將一些具體的資源抽象化,比如:

  • 建立會員資料:POST /member
  • 取得會員資料:GET /member/1
  • 更新會員資料:PUT /member/1
  • 刪除會員資料:DELETE /member/1

那,如果今天我要做的事情是「登入會員」,該如何抽象成 HTTP method 與 URI 呢?

嗯。。。頂多會把「會員」抽象化成 member,但沒有一個 HTTP method 叫做「登入」呀QQ!

所以如果是我,肯定就直接放棄人生

啊算了啦!就開一個 POST /login 的 API 啦!

這就是缺點第二點提到的,正確將資源抽象化,真的不是一件容易的事情。而這也是大部分沒有搞懂 RESTful API 的人會寫出來的。

我看到的解答是,無論登入與登出,都是針對「session」這個「資源」的建立與刪除罷了

  • 登入會員:POST /session
  • 登出會員:DELETE /session

我突然就豁然開朗了!

當然中間省略了一大堆細節啦,不過確實讓我對「資源」的抽象化上了一課!

RESTful API 適合什麼情境?

由於是以「資源」為主體,透過 API 去操作資源時,一次就是針對一個資源,如果有什麼複雜的需求,就是要多發幾次 request 才能辦到,聽起來雖然很麻煩很像缺點,但如果是開放給第三方串接的 API,大多時候你是不知道「別人會怎樣使用你的資料」,既然都不知道,那一次一個資源為單位的 request,其實是非常明確切分的,反正要怎麼組合這些資料,是串接者自己的事情了。

RESTful API 其實真的是看狀況使用,畢竟到頭來 REST 就是個風格,只要大家能夠遵守一致,其實影響不會那麼大。

結語

心智圖放大版

其實 RESTful API 應該還有一卡車的特性可以寫,我這邊只記錄下自己最容易混淆的部分,有興趣的話可以再到下方參考資料看看,如果對於我寫的有疑問,也歡迎留言討論囉!

認真了解 RESTful API 的風格後,對於自己以前開過的 API 真的是不堪回首(掩面),真的用了不少動詞在 URI 裡面,但有不少 API 的確是因為考量到效率,期待在一次 API request 做很多事,才打破了這個規則,真要說怎樣才是對的,我想整個團隊是否有一致的共識,可能是更重要的!

參考資料

維基百科
淺談 RESTful web API
理解 RESTful API


上一篇
Day 14 - 為什麼要用 React Router
下一篇
Day 16 - 為什麼要用 GraphQL
系列文
前端技能樹的十萬個為什麼30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言